package com.zheng.controller;

import com.sun.mail.imap.IMAPStore;
import com.zheng.common.Result;
import com.zheng.config.WyMailConfig;
import com.zheng.entity.MailDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.*;

import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.search.*;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.*;

/**
 * @author: ztl
 * @date: 2025/07/31 22:29
 * @desc:
 */

@RestController
@RequestMapping("/wyemail")
@Slf4j
public class WyEmailController {

    @Autowired
    private JavaMailSender javaMailSender;

    //发件人邮箱
    @Value("${spring.mail.username}")
    private String from;

    @Autowired
    private WyMailConfig mailConfig;

    /**
     * 不带附件发送邮件
     * addressee 收件人邮箱
     * subject 邮件标题
     * content 邮件内容
     * @return ResultVO
     */
    @PostMapping("/send")
    public Result sendEmail(@RequestBody MailDto mail) throws AddressException {
        //判断文件格式是否正确
        //获取收件人邮箱
        String addressee = mail.getAddressee();
        if(!addressee.contains("@163.com")){
            return Result.error("502","邮箱格式错误");
        }
        //生成随机6位数字
        StringBuilder sb = (StringBuilder)imgCode().getData();

        mail.setSubject(mailConfig.getSubject());
        mail.setContent(mailConfig.getContentPrefix()+sb+mailConfig.getContentSuffix());

        SimpleMailMessage mailMessage = new SimpleMailMessage();
        // 发件人邮箱,与配置文件中保持一致,所以直接从配置文件绑定过来了
//        mailMessage.setFrom(String.valueOf(new InternetAddress("大浪8" + "<" + from + ">")));
        mailMessage.setFrom(from);
        // 收件人
        mailMessage.setTo(mail.getAddressee());
        // 标题
        mailMessage.setSubject(mail.getSubject());
        // 内容, 第一个参数为邮箱内容, 第二个参数为是否启用html格式,
        // 如果开启, 那么第一个参数如果有html标签, 会自动识别, 邮件样式更好看
        mailMessage.setText(mail.getContent());
        try {
            javaMailSender.send(mailMessage);
            return Result.success(sb.toString()); // 返回验证码
        } catch (MailAuthenticationException e) {
            return Result.error("530", "认证失败，请检查授权码和SSL配置");
        } catch (MailSendException e) {
            return Result.error("531", "邮件发送失败，请检查网络和配置");
        }
        //返回验证码
//        return Result.success();
    }

    @GetMapping("/getImgCode")
    public Result imgCode(){
        //生成随机6位数字
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(secureRandom.nextInt(10));
        }
        return Result.success(sb);
    }

    /**
     * 新增：接收最新的N封邮件
     * @param count 要获取的邮件数量（默认10封）
     * @return 邮件列表（包含发件人、主题、内容）
     */
    @GetMapping("/receive")
    public Result receiveEmails(@RequestParam(defaultValue = "10") int count) {
        try {
            // 1. 配置IMAP服务器
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imap");
            props.setProperty("mail.imap.host", "imap.163.com");
            props.setProperty("mail.imap.port", "993");
            props.setProperty("mail.imap.ssl.enable", "true");
            props.setProperty("mail.imap.auth", "true");



            //这部分就是解决异常的关键所在，设置IAMP ID信息
            HashMap IAM = new HashMap();
            //带上IMAP ID信息，由key和value组成，例如name，version，vendor，support-email等。
            // 这个value的值随便写就行
            IAM.put("name","myname");
            IAM.put("version","1.0.0");
            IAM.put("vendor","myclient");
            IAM.put("support-email","testmail@test.com");



            // 2. 创建Session并连接邮件服务器
            Session session = Session.getInstance(props);
//            Store store = session.getStore("imap");
            IMAPStore store = (IMAPStore) session.getStore("imap");
//            store.connect("imap.163.com", from, "LHvwWArkg8ptRTaw"); // 使用授权码登录
            store.connect("zhengtianliang156@163.com", "LHvwWArkg8ptRTaw"); // 使用授权码登录
            store.id(IAM);

            // 3. 打开收件箱
            Folder inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_WRITE); // 只读模式

            // 4. 获取最新的N封邮件
            Message[] messages = inbox.getMessages();
            int totalMessages = Math.min(count, messages.length);

            List<Map<String, String>> emailList = new ArrayList<>();
            for (int i = messages.length - 1; i >= messages.length - totalMessages; i--) {
                Message message = messages[i];
                Map<String, String> emailInfo = new HashMap<>();

                emailInfo.put("from", InternetAddress.toString(message.getFrom()));
                emailInfo.put("subject", message.getSubject());
                emailInfo.put("content", message.getContent().toString());
                emailInfo.put("date", message.getSentDate().toString());

                emailList.add(emailInfo);
            }

            // 5. 关闭连接
            inbox.close(false);
            store.close();

            return Result.success(emailList);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("500", "接收邮件失败: " + e.getMessage());
        }
    }


    /**
     * 新增：获取最新邮件中的 PDF 附件
     * @param count 检查的最新邮件数量（默认5封）
     * @return 包含 PDF 附件的 Base64 编码和文件名
     */
    @GetMapping("/pdfAttachments")
    public Result getPdfAttachments(@RequestParam(defaultValue = "5") int count) {
        try {
            // 1. 配置IMAP服务器
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imap");
            props.setProperty("mail.imap.host", "imap.163.com");
            props.setProperty("mail.imap.port", "993");
            props.setProperty("mail.imap.ssl.enable", "true");
            props.setProperty("mail.imap.auth", "true");



            //这部分就是解决异常的关键所在，设置IAMP ID信息
            HashMap IAM = new HashMap();
            //带上IMAP ID信息，由key和value组成，例如name，version，vendor，support-email等。
            // 这个value的值随便写就行
            IAM.put("name","myname");
            IAM.put("version","1.0.0");
            IAM.put("vendor","myclient");
            IAM.put("support-email","testmail@test.com");



            // 2. 创建Session并连接邮件服务器
            Session session = Session.getInstance(props);
//            Store store = session.getStore("imap");
            IMAPStore store = (IMAPStore) session.getStore("imap");
//            store.connect("imap.163.com", from, "LHvwWArkg8ptRTaw"); // 使用授权码登录
            store.connect("zhengtianliang156@163.com", "LHvwWArkg8ptRTaw"); // 使用授权码登录
            store.id(IAM);

            // 3. 打开收件箱
            Folder inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_ONLY);

            // 4. 获取最新的N封邮件
            Message[] messages = inbox.getMessages();
            int totalMessages = Math.min(count, messages.length);

            List<Map<String, String>> pdfAttachments = new ArrayList<>();

            // 5. 遍历邮件，查找PDF附件
            for (int i = messages.length - 1; i >= messages.length - totalMessages; i--) {
                Message message = messages[i];
                if (message.isMimeType("multipart/*")) {
                    Multipart multipart = (Multipart) message.getContent();
                    for (int j = 0; j < multipart.getCount(); j++) {
                        BodyPart bodyPart = multipart.getBodyPart(j);
                        if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
                            String fileName = bodyPart.getFileName();
                            if (fileName != null && fileName.toLowerCase().endsWith(".pdf")) {
                                // 读取PDF附件
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                bodyPart.getDataHandler().writeTo(outputStream);
                                byte[] pdfBytes = outputStream.toByteArray();

                                // 转换为Base64
                                String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes);

                                Map<String, String> attachmentInfo = new HashMap<>();
                                attachmentInfo.put("fileName", fileName);
                                attachmentInfo.put("base64Content", base64Pdf);
                                pdfAttachments.add(attachmentInfo);
                            }
                        }
                    }
                }
            }

            // 6. 关闭连接
            inbox.close(false);
            store.close();

            return Result.success(pdfAttachments);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("500", "获取PDF附件失败: " + e.getMessage());
        }
    }


    /**
     * 分页+ 只要未读的邮件
     * @param count
     * @return
     */
    @GetMapping("/receivePage")
    public Result receiveUnreadEmailsByPage(@RequestParam(defaultValue = "1") int page) {
        IMAPStore store = null;
        Folder inbox = null;
        try {
            // 1. 配置IMAP服务器（163邮箱使用IMAP协议）
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imap");
            props.setProperty("mail.imap.host", "imap.163.com");
            props.setProperty("mail.imap.port", "993");
            props.setProperty("mail.imap.ssl.enable", "true");
            props.setProperty("mail.imap.auth", "true");

            // 设置IMAP ID信息（解决163邮箱认证问题）
            HashMap<String, String> IAM = new HashMap<>();
            IAM.put("name", "myname");
            IAM.put("version", "1.0.0");
            IAM.put("vendor", "myclient");
            IAM.put("support-email", "testmail@test.com");

            // 2. 创建Session并连接邮件服务器
            Session session = Session.getInstance(props);
            store = (IMAPStore) session.getStore("imap");
            store.connect("zhengtianliang156@163.com", "LHvwWArkg8ptRTaw");
            store.id(IAM);

            // 3. 打开收件箱（读写模式，才能修改邮件状态）
            inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_WRITE);

            // 4. 筛选未读邮件（Flags.Flag.SEEN = false）
            Flags seenFlag = new Flags(Flags.Flag.SEEN);
            FlagTerm unseenFlagTerm = new FlagTerm(seenFlag, false);
            Message[] unreadMessages = inbox.search(unseenFlagTerm);

            // 5. 分页处理（每页2条）
            int pageSize = 2;
            int totalUnread = unreadMessages.length;
            int totalPages = (int) Math.ceil((double) totalUnread / pageSize);

            // 页码校验
            if (page < 1 || (page > totalPages && totalPages > 0)) {
                return Result.error("400", "页码超出范围");
            }

            // 6. 获取当前页数据
            List<Map<String, String>> emailList = new ArrayList<>();
            int startIdx = (page - 1) * pageSize;
            int endIdx = Math.min(startIdx + pageSize, totalUnread);

            for (int i = startIdx; i < endIdx; i++) {
                Message message = unreadMessages[i];
                Map<String, String> emailInfo = new HashMap<>();

                emailInfo.put("from", InternetAddress.toString(message.getFrom()));
                emailInfo.put("subject", message.getSubject());
                emailInfo.put("content", getTextFromMessage(message)); // 改进的内容获取方法
                emailInfo.put("date", message.getSentDate().toString());

                // 标记为已读
                message.setFlag(Flags.Flag.SEEN, true);
                emailList.add(emailInfo);
            }

            // 7. 返回分页结果
            Map<String, Object> result = new HashMap<>();
            result.put("emails", emailList);
            result.put("currentPage", page);
            result.put("pageSize", pageSize);
            result.put("totalUnread", totalUnread);
            result.put("totalPages", totalPages);

            // 8. 关闭连接（保存更改）
            inbox.close(true);
            store.close();

            return Result.success(result);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (inbox != null && inbox.isOpen()) inbox.close(false);
                if (store != null && store.isConnected()) store.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return Result.error("500", "接收邮件失败: " + e.getMessage());
        }
    }

    @GetMapping("/receivePage1")
    public Result receiveUnreadEmailsByPage(@RequestParam(defaultValue = "1") int page,
                                            HttpServletResponse response) {
        IMAPStore store = null;
        Folder inbox = null;
        try {
            // 1. 配置IMAP服务器
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imap");
            props.setProperty("mail.imap.host", "imap.163.com");
            props.setProperty("mail.imap.port", "993");
            props.setProperty("mail.imap.ssl.enable", "true");
            props.setProperty("mail.imap.auth", "true");

            // 设置IMAP ID信息
            HashMap<String, String> IAM = new HashMap<>();
            IAM.put("name", "myname");
            IAM.put("version", "1.0.0");
            IAM.put("vendor", "myclient");
            IAM.put("support-email", "testmail@test.com");

            // 2. 创建Session并连接邮件服务器
            Session session = Session.getInstance(props);
            store = (IMAPStore) session.getStore("imap");
            store.connect("zhengtianliang156@163.com", "LHvwWArkg8ptRTaw");
            store.id(IAM);

            // 3. 打开收件箱
            inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_WRITE);

            // 4. 筛选未读邮件
            Flags seenFlag = new Flags(Flags.Flag.SEEN);
            FlagTerm unseenFlagTerm = new FlagTerm(seenFlag, false);
            Message[] unreadMessages = inbox.search(unseenFlagTerm);

            // 5. 分页处理
            int pageSize = 2;
            int totalUnread = unreadMessages.length;
            int totalPages = (int) Math.ceil((double) totalUnread / pageSize);


            // 6. 处理邮件和附件
            List<Map<String, Object>> emailList = new ArrayList<>();
            int startIdx = (page - 1) * pageSize;
            int endIdx = Math.min(startIdx + pageSize, totalUnread);

            for (int i = startIdx; i < endIdx; i++) {
                Message message = unreadMessages[i];
                Map<String, Object> emailInfo = new HashMap<>();

                // 基础信息
                emailInfo.put("from", InternetAddress.toString(message.getFrom()));
                emailInfo.put("subject", message.getSubject());
                emailInfo.put("content", getTextFromMessage(message));
                emailInfo.put("date", message.getSentDate().toString());

                if (message.isMimeType("multipart/*")) {
                    Multipart multipart = (Multipart) message.getContent();
                    for (int j = 0; j < multipart.getCount(); j++) {
                        BodyPart bodyPart = multipart.getBodyPart(j);
                        if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
                            String fileName = bodyPart.getFileName();
                            if (fileName != null && fileName.toLowerCase().endsWith(".ofd")) {
                                // 读取PDF附件
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                bodyPart.getDataHandler().writeTo(outputStream);
                                byte[] pdfBytes = outputStream.toByteArray();

                                // 转换为Base64
                                String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes);

                                Map<String, String> attachmentInfo = new HashMap<>();
                                attachmentInfo.put("fileName", fileName);
                                attachmentInfo.put("base64Content", base64Pdf);
                                emailInfo.put("date", message.getSentDate().toString());
                                emailInfo.put("attachmentInfo1", attachmentInfo);
                            }
                        }
                    }
                }

                // 处理附件
                List<Map<String, String>> attachments = processAttachments(message, response);
                emailInfo.put("attachments", attachments);

                // 标记为已读
//                message.setFlag(Flags.Flag.SEEN, true);
                emailList.add(emailInfo);
            }

            // 7. 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("emails", emailList);
            result.put("currentPage", page);
            result.put("pageSize", pageSize);
            result.put("totalUnread", totalUnread);
            result.put("totalPages", totalPages);

            return Result.success(result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("500", "接收邮件失败: " + e.getMessage());
        } finally {
            try {
                if (inbox != null && inbox.isOpen()) inbox.close(true);
                if (store != null && store.isConnected()) store.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private List<Map<String, String>> processAttachments(Message message, HttpServletResponse response)
            throws Exception {
        List<Map<String, String>> attachments = new ArrayList<>();

        if (message.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) message.getContent();

            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);

                if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
                    String fileName = bodyPart.getFileName();
                    String fileType = bodyPart.getContentType();
                    long fileSize = bodyPart.getSize();

                    // 附件信息
                    Map<String, String> attachmentInfo = new HashMap<>();
                    attachmentInfo.put("fileName", fileName);
                    attachmentInfo.put("fileType", fileType);
                    attachmentInfo.put("fileSize", String.valueOf(fileSize));
                    attachmentInfo.put("downloadUrl", "/downloadAttachment?fileName=" +
                            URLEncoder.encode(fileName, "UTF-8"));

                    attachments.add(attachmentInfo);

                    // 保存附件到临时目录
                }
            }
        }
        return attachments;
    }

//    private String getTextFromMessage(Message message) throws Exception {
//        if (message.isMimeType("text/plain")) {
//            return message.getContent().toString();
//        } else if (message.isMimeType("multipart/*")) {
//            Multipart multipart = (Multipart) message.getContent();
//            for (int i = 0; i < multipart.getCount(); i++) {
//                BodyPart bodyPart = multipart.getBodyPart(i);
//                if (bodyPart.isMimeType("text/plain")) {
//                    return bodyPart.getContent().toString();
//                }
//            }
//        }
//        return "无法解析的邮件内容";
//    }

    private String getTextFromMessage(Message message) throws Exception {
        if (message.isMimeType("text/plain")) {
            return message.getContent().toString();
        } else if (message.isMimeType("multipart/*")) {
            return processMultipart((Multipart) message.getContent());
        } else if (message.isMimeType("text/html")) {
            return htmlToText(message.getContent().toString());
        }
        return "无法解析的邮件内容";
    }

    /**
     * String text = html.replaceAll("<[^>]+>", "").replaceAll("&nbsp;", " ");
     * @param multipart
     * @return
     * @throws Exception
     */
    private String processMultipart(Multipart multipart) throws Exception {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < multipart.getCount(); i++) {
            BodyPart bodyPart = multipart.getBodyPart(i);

            // 处理multipart/related类型的嵌套内容
            if (bodyPart.isMimeType("multipart/related")) {
                result.append(processMultipart((Multipart) bodyPart.getContent()));
            }
            // 处理其他multipart类型（如mixed/alternative）
            else if (bodyPart.getContent() instanceof Multipart) {
                result.append(processMultipart((Multipart) bodyPart.getContent()));
            }
            // 处理纯文本内容
            else if (bodyPart.isMimeType("text/plain")) {
                result.append(bodyPart.getContent().toString());
            }
            // 处理HTML内容
            else if (bodyPart.isMimeType("text/html")) {
                result.append(htmlToText(bodyPart.getContent().toString()));
            }
            // 可以添加对其他内容类型的处理...
        }

        return result.toString().trim();
    }

    private String htmlToText(String html) {
        // 使用JSoup去除HTML标签，保留文本内容
        return html;
    }


    @GetMapping("/query4TimeRange")
    public Result query4TimeRange(@RequestParam(defaultValue = "1") int page,
                                            HttpServletResponse response) {
        IMAPStore store = null;
        Folder inbox = null;
        try {
            // 1. 配置IMAP服务器
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", "imap");
            props.setProperty("mail.imap.host", "imap.163.com");
            props.setProperty("mail.imap.port", "993");
            props.setProperty("mail.imap.ssl.enable", "true");
            props.setProperty("mail.imap.auth", "true");

            // 设置IMAP ID信息
            HashMap<String, String> IAM = new HashMap<>();
            IAM.put("name", "myname");
            IAM.put("version", "1.0.0");
            IAM.put("vendor", "myclient");
            IAM.put("support-email", "testmail@test.com");

            // 2. 创建Session并连接邮件服务器
            Session session = Session.getInstance(props);
            store = (IMAPStore) session.getStore("imap");
            store.connect("zhengtianliang156@163.com", "LHvwWArkg8ptRTaw");
            store.id(IAM);

            // 3. 打开收件箱
            inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_WRITE);

            Calendar startDate = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")); // 使用CST时区（中国标准时间）
            startDate.set(2025, Calendar.AUGUST, 5, 11, 0, 0);
            startDate.set(Calendar.MILLISECOND, 0);

            Calendar endDate = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
            endDate.set(2025, Calendar.AUGUST, 7, 22, 40, 0);
            endDate.set(Calendar.MILLISECOND, 0);

            SearchTerm olderThan = new SentDateTerm(ComparisonTerm.LE, endDate.getTime());
            SearchTerm newerThan = new SentDateTerm(ComparisonTerm.GE, startDate.getTime());
            SearchTerm andTerm = new AndTerm(olderThan, newerThan);

            // 获取符合条件的邮件
            Message[] unreadMessages = inbox.search(andTerm);

            log.info("queryEmailForEleJourney###查询邮箱{}, 时间范围{}到{}, 一共有{}条邮件",
                    "zhengtianliang156@163.com",
                    startDate.getTime(),
                    endDate.getTime(),
                    unreadMessages.length);
            // 5. 分页处理
            int pageSize = 20;
            int totalUnread = unreadMessages.length;
            int totalPages = (int) Math.ceil((double) totalUnread / pageSize);


            // 6. 处理邮件和附件
            List<Map<String, Object>> emailList = new ArrayList<>();
            int startIdx = (page - 1) * pageSize;
            int endIdx = Math.min(startIdx + pageSize, totalUnread);

            for (int i = startIdx; i < endIdx; i++) {
                Message message = unreadMessages[i];
                Map<String, Object> emailInfo = new HashMap<>();

                // 基础信息
                emailInfo.put("from", InternetAddress.toString(message.getFrom()));
                emailInfo.put("subject", message.getSubject());
//                emailInfo.put("content", getTextFromMessage(message));
                emailInfo.put("date", message.getSentDate().toString());


                // 处理附件
                List<Map<String, String>> attachments = processAttachments(message, response);
                emailInfo.put("attachments", attachments);

                emailList.add(emailInfo);
            }

            // 7. 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("emails", emailList);
            result.put("currentPage", page);
            result.put("pageSize", pageSize);
            result.put("totalUnread", totalUnread);
            result.put("totalPages", totalPages);

            return Result.success(result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("500", "接收邮件失败: " + e.getMessage());
        } finally {
            try {
                if (inbox != null && inbox.isOpen()) inbox.close(true);
                if (store != null && store.isConnected()) store.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
